<?php
/*
 * @Description    : 基础控制器
 * @Version        : 1.0.0
 * @Author         : QianLong
 * @Date           : 2021-04-26 09:05:53
 * @LastEditors    : QianLong
 * @LastEditTime   : 2022-05-30 15:53:13
 */

namespace app\api\controller;

use app\api\model\AuthMenu;
use app\api\model\Manager;
use app\BaseController;
use app\common\logic\Auth;
use app\common\logic\Security;
use app\common\service\QlRedis;
use app\lib\exception\ApiException;
use think\facade\Request;

class Base extends BaseController
{
  protected $redis;
  protected $user;
  protected $rulesId;
  protected $p_mid;
  public function initialize()
  {
    $this->redis = new QlRedis();
    $this->user = $this->checkUser($this->redis);
    // 判断用户是否有访问此接口的权限
    // 接口白名单
    $app = app('http')->getName();
    $whiteApi = [$app . '/user/info', $app . '/user/getrole', $app . '/user/getmenu', $app . '/menu/get_menu_with_level', $app . '/user/refresh_token'];
    $apiUrl = $app . '/' . parse_name(Request::controller()) . '/' . parse_name(Request::action());
    $ruleString = '';
    if (in_array($apiUrl, $whiteApi) != true && $this->user['is_admin'] != 1) {
      // 构建权限接口数组
      // $actionUrlList = getRedisCache('getAuthApiListById-' . $this->user['id'], 'json');
      // if (empty($actionUrlList)) {
      $ruleString = Auth::getRuleId($this->user['groupId']);
      $wherePermission[] = ['id', 'in', $ruleString];
      $hasPermission = AuthMenu::field('actionUrl')->where($wherePermission)->select()->toArray();
      $actionUrlList = [];
      foreach ($hasPermission as &$vo) {
        array_push($actionUrlList, $vo['actionUrl']);
      }
      //   putRedisCache('getAuthApiListById-' . $this->user['id'], $actionUrlList, config('app.SYS_STATIC.redis_expire'), 'json');
      // }
      if (!in_array($apiUrl, $actionUrlList)) {
        throw new ApiException('您没有权限使用此功能，请如使用，请联系您的上级管理员进行处理。', -99);
      }
    }
    // 手机号进行脱敏显示
    $this->user['phone'] = dataTuomin($this->user['phone'], 3, 5);
    $this->user['roleId'] = $this->user['groupId'];
    $this->uid = (int) $this->user['id'];
    $this->p_mid = (int) $this->user['manager_id'];
    $this->rulesId = $ruleString;
    $this->time = time();
  }
  public function checkUser($redis)
  {
    // JWT用户令牌认证，令牌内容获取
    $getUserToken = request()->header('Authorization');
    if (empty($getUserToken)) {
      throw new ApiException('token 丢失或无效，请重新登录', -2);
    }
    $userTokenArray = explode(':', $getUserToken);
    $getUserToken = $userTokenArray[0];
    $getUserToken = explode(' ', $getUserToken);
    $getUserToken = $getUserToken[1];
    $userToken = think_decrypt($getUserToken);
    $payload   = json_decode($userToken, true);
    if ($payload === false || empty($payload['uid']) || empty($payload['loginTime'])) {
      throw new ApiException('token 丢失或无效，请重新登录', -2);
    }
    // 登录是否有效判断
    if ((int) $redis->exists('token-' . $payload['uid']) < 1) {
      if (parse_name(Request::controller()) . '/' . parse_name(Request::action()) != 'user/refresh_token') {
        throw new ApiException('登录已过期，请重新登录', -99);
      } else {
        if (isset($payload['refresh_key']) && !empty($payload['refresh_key'])) {
          Security::token_refresh($payload['refresh_key'], $redis);
          Security::token_refresh_limit($payload['uid'], $redis);
        } else {
          throw new ApiException('登录已过期，请重新登录', -2);
        }
      }
    } else if ($redis->ttl('token-' . $payload['uid']) == -1) {
      $redis->del('token-' . $payload['uid']);
      throw new ApiException('登录已过期，请重新登录', -2);
    }
    // 实时用户数据
    $user = Manager::field('id,password,phone,status,is_admin,groupId,manager_id,alpha_dev,avatar,username,email,login_time,wechat_nickname,ww_user_id')->where('id', $payload['uid'])->find();
    //是否多设备登录
    if ($user['login_time'] != $payload['loginTime'] && config('multi_login') == false) {
      throw new ApiException('当前账号已在其他设备登录，当前登录已失效，请重新登录', -2);
    }
    //认证：状态
    if ($user['status'] != 1) {
      throw new ApiException('用户状态异常或被封禁，请联系管理员进行处理。', -3);
    }
    if (empty($user['groupId'])) {
      throw new ApiException('当前账户无任何权限，无法登录', -2);
    }
    if (!isset($payload['password']) || empty($payload['password']) || $user['password'] != $payload['password']) {
      throw new ApiException('当前账户帐号或密码已被修改，请重新登录', -2);
    }
    unset($user['password']);
    $user['avatar'] = (!empty($user['avatar'])) ? $user['avatar'] : config('app.SYS_STATIC.defaultAvatar');
    Security::limit_check($user['id'], $payload['refresh_key'], $redis);
    return $user;
  }
}
